//
//  TQRecordHelper.swift
//  TQMedia
//
//  Created by XieLB on 2018/9/26.
//  Copyright © 2018年 XieLB. All rights reserved.
//

import UIKit
import XMNAudio

class TQRecordHelper: NSObject {
    // MARK:- 单例
    static let instance = TQRecordHelper()
    static func share() -> TQRecordHelper {
        return instance
    }
    /// 播放器
    var audioPlayer: XMNAudioPlayer?
    /// 播放闭包
    var playRecordCloser: (() -> Void)?
    /// 停止闭包
    var stopRecordCloser: (() -> Void)?
    /// 下载状态变化触发闭包(下载状态 1：暂停、2：下载中、3：完成)
    var downloadStateChangeCloser: ((Int) -> Void)?
    ///
    var jmSoundID: SystemSoundID = 0
    
    
    /// 播放本地录音接口(项目本身资源)
    func playLocalRecord(_ params: Dictionary<String, Any>) {

        let soundName = (params["soundName"] as? String) ?? "default.wav"
        // 获取声音文件路径
        let soundPath: String = Bundle.main.path(forResource: soundName, ofType: nil)!
        let soundUrl = URL(string: soundPath)
        // 将声音URL转换成声音ID
        AudioServicesCreateSystemSoundID(CFBridgingRetain(soundUrl) as! CFURL, &jmSoundID)
        
        // 添加音频结束时的回调
        let observer = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())
        AudioServicesAddSystemSoundCompletion(jmSoundID, nil, nil, { (soundID, inClientData) -> Void in
//            let mySelf = Unmanaged<AnyObject>.fromOpaque(inClientData!).takeUnretainedValue()
            TQRecordHelper.share().audioServicesPlaySystemSoundCompleted(soundID: TQRecordHelper.share().jmSoundID)
        }, observer)
        AudioServicesPlaySystemSound(jmSoundID)
    }
    
    //音频结束时的回调
    func audioServicesPlaySystemSoundCompleted(soundID: SystemSoundID) {
        AudioServicesRemoveSystemSoundCompletion(soundID)
        AudioServicesDisposeSystemSoundID(soundID)
    }
    
    /// 播放录音接口
    func playRecord(_ params: Dictionary<String, Any>) {
        
        print("play record")
        
        //暂停之前播放
        stopRecord(params)
        
        let downloadUrl = params["downloadUrl"] as! String
        let fname = params["fname"] as! String
        //如果没有网络URL，直接读取本地录音文件
        if downloadUrl.count == 0 {
            playAudioFile(filePath: fname)
        }
        
        //开启下载任务
        let task = RequestDownloadTask()
        task.delegate = self
        task.url = downloadUrl
        task.objTag = fname
        task.outFilePath = getFilePath(fileName: fname)
        if HttpDownloadManager.sharedInstance().currentTaskExsit(fname) == false {
            HttpDownloadManager.sharedInstance().addTask(fname, obj: task)
        }
        HttpDownloadManager.sharedInstance().startTask(fname)
    }
    
    /// 停止播放接口
    func stopRecord(_ params: Dictionary<String, Any>) {
        
        print("stop record")
        
        guard audioPlayer?.status == .playing  ||  audioPlayer?.status == .idle else {
            return
        }
        audioPlayer?.stop()
    }
    
    // 开始播放触发闭包
    func getPlayRecordCloser(_ params: Dictionary<String, Any>) {
        playRecordCloser = params["closer"] as? (() -> Void)
    }
    
    // 停止播放触发闭包
    func getStopRecordCloser(_ params: Dictionary<String, Any>) {
        stopRecordCloser = params["closer"] as? (() -> Void)
    }
    
    /// 下载状态变化触发闭包(下载状态 1：暂停、2：下载中、3：完成)
    func downloadStateChangeCloser(_ params: Dictionary<String, Any>) {
        downloadStateChangeCloser = params["closer"] as? ((Int) -> Void)
    }
    
    deinit {
        if audioPlayer != nil {
            audioPlayer!.removeObserver(self, forKeyPath: "status")
        }
    }
}


// MARK:- 下载协议
extension TQRecordHelper: HttpDownloadDelegate {
    
    func downloadBegin(_ objTask: RequestDownloadTask?) {
        downloadStateChangeCloser?(2)
    }
    
    func changeProgress(_ progress: CGFloat, obj objTask: RequestDownloadTask?) {
        
    }
    
    func changeState(_ objTask: RequestDownloadTask?) {
        if objTask?.state == Int(STATE_PAUSE) {
            downloadStateChangeCloser?(1)
        }
    }
    
    //task download done 下载完成
    func downloadDone(_ objTask: RequestDownloadTask?) {
        downloadStateChangeCloser?(3)
        //
        //        (objTask?.objTag as? JMRecordItemModel)?.state = "3"
        //
        //        let taskModel = objTask?.objTag as? JMRecordItemModel
        //        //更新数据
        //        _ = JMVoiceDataBaseTool.updateDownloadData(account: account, imei: imei, record: taskModel!)
        //删除任务
        HttpDownloadManager.sharedInstance().delTask(objTask?.objTag as! String)
        //开始播放
        playAudioFile(filePath: objTask?.outFilePath)
    }
    
    func downloadFail(_ objTask: RequestDownloadTask?) {
        downloadStateChangeCloser?(1)
    }
    
    func pauseAllTask() {
        HttpDownloadManager.sharedInstance().stopAllTask()
    }
}

// MARK:- 播放
extension TQRecordHelper {
    
    /// 下载文件目录地址
    func getFilePath(fileName: String?) -> String? {
        let directory = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).first!
        let path = directory + "DownloadImagesAndAudio"
        //创建录音文件路径, 若不存在就创建一个
        if FileManager.default.fileExists(atPath: path) == false {
            do {
                try FileManager.default.createDirectory(atPath: path, withIntermediateDirectories: true, attributes: nil)
            } catch  {
                
            }
        }
        return "\(path)/\(fileName ?? "")"
    }
    
    /// 播放文件
    func playAudioFile(filePath: String?) {
        //文件不存在
        if FileManager.default.fileExists(atPath: filePath ?? "") == false {
            return
        }
        //去除监听
        if audioPlayer != nil {
            audioPlayer!.removeObserver(self, forKeyPath: "status")
        }
        //开始播放
        let file = XMNTestAudioFile()
        file.audioFileUrl = URL(fileURLWithPath: filePath ?? "")
        audioPlayer = XMNAudioPlayer(audioFile: file)
        audioPlayer?.addObserver(self, forKeyPath: "status", options: .old, context: nil)
        audioPlayer?.play()
    }
    
    /// 播放完成后的回调 KVO 监听
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        
        if (keyPath == "status") {
            //播放完成
            if audioPlayer?.status == .finished {
                stopRecordCloser?()
            }
            //开始播放
            if audioPlayer?.status == .playing {
                playRecordCloser?()
            }
        }
    }
}

//录音播放
class XMNTestAudioFile: NSObject, XMNAudioFile {
    
    //播放的音频的 URL地址, 一定要使用[NSURL fileURLWithPath:filePath];初始化文件地址
    var audioFileUrl: URL!
    
    func audioFileURL() -> URL! {
        return audioFileUrl
    }
    
    //判断文件的类型
    func fileTypeID() -> AudioFileTypeID {
        if (audioFileUrl.pathExtension == "mp3") {
            return kAudioFileMP3Type
        } else if (audioFileUrl.pathExtension == "amr") {
            return kAudioFileAMRType
        }
        return AudioFileTypeID(0)
    }
}
